package com.jmp.autocofiguration.web;


import lombok.extern.slf4j.Slf4j;
import one.stand.advice.ResultEnum;
import one.stand.exception.ParamException;
import one.stand.model.ResultModel;
import one.stand.util.OneIllegalArgumentException;
import one.stand.util.Result;
import one.stand.util.ResultUtil;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: QIK
 * @CreateDate: 2019/4/18 22:40
 */
@ControllerAdvice(annotations = RestController.class)
@ResponseBody
@Slf4j
public class ExceptionHandlerAdvice {
    /**
     * 400 - Bad Request
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result handleHttpMessageNotReadableException(HttpMessageNotReadableException e, HttpServletResponse response) {
        return handler(e, "参数解析失败", response);
    }

    /**
     * 405 - Method Not Allowed
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e, HttpServletResponse response) {
        return handler(e, "不支持当前请求方法", response);
    }

    /**
     * 415 - Unsupported Media Type
     */
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public Result handleHttpMediaTypeNotSupportedException(Exception e, HttpServletResponse response) {
        return handler(e, "不支持当前媒体类型", response);
    }

    private Result handler(Exception e, String msg, HttpServletResponse response) {
        response.setStatus(HttpStatus.OK.value());
        int code = e instanceof OneIllegalArgumentException ? ((OneIllegalArgumentException) e).getCode() : ResultEnum.ERROR.getCode();
        log.error(code + ":" + msg, e);
        return ResultUtil.fail(code, msg);
    }

    @ExceptionHandler(ParamException.class)
    public ResultModel exceptionHandle(ParamException e) {
        return ResultModel.fail(ResultEnum.PARAM_CHECK);
    }

    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public ResultModel exceptionHandle(SQLIntegrityConstraintViolationException e) {
        log.error(e.getMessage(), e);
        return ResultModel.fail(ResultEnum.DUPLICATE_KEY);
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public ResultModel exceptionHandle(DuplicateKeyException e) {
        log.error(e.getMessage(), e);
        return ResultModel.fail(ResultEnum.DUPLICATE_KEY);
    }

    @ResponseBody
    @ExceptionHandler(Exception.class)
    public Map<String, String> exceptionHandle(Exception e) {
        log.error(e.getMessage(), e);

        String code = "500";
        String msg = "网络错误";
        if (e instanceof IllegalArgumentException) {
            msg = e.getMessage();
            if (e instanceof OneIllegalArgumentException) {
                code = String.valueOf(((OneIllegalArgumentException) e).getCode());
            }
        }

        Map<String, String> result = new HashMap<>(3);
        result.put("code", code);
        result.put("message", msg);
        result.put("success", "true");
        return result;
    }
}
